home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / blf082b / address.c next >
C/C++ Source or Header  |  1993-11-16  |  12KB  |  583 lines

  1. /*
  2.  *    BloufGate
  3.  *    Address processing 
  4.  *
  5.  *    Public Domain: may be copied and sold freely
  6.  */
  7.  
  8. #include    "blouf.h"
  9.  
  10. /*#define sdc(a,b) strnicmp(a,b,3)==0*/
  11.  
  12. /*
  13.  *    Convert string to date struct
  14.  */
  15.  
  16. static char *day[]={"sun","mon","tue","wed","thu","fri","sat"};
  17. static char *month[]={"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};
  18.  
  19. void strdate2tm(char *str, struct tm *out)
  20. {
  21.     char *ptr;
  22.     int i;
  23.     time_t tt;
  24.  
  25.     out->tm_sec=0;
  26.     out->tm_min=0;
  27.     out->tm_hour=0;
  28.     out->tm_mday=0;
  29.     out->tm_mon=0;
  30.     out->tm_year=0;
  31.     out->tm_wday=0;
  32.     out->tm_yday=0;
  33.     out->tm_isdst=0;
  34.  
  35.     ptr=strtok(str,", ");
  36.  
  37.     do
  38.     {
  39.         if(!ptr) break;
  40.  
  41.         if(isalpha(*ptr))
  42.         {
  43.             for(i=0;i<7;i++)
  44.             {
  45.                 if(strnicmp(day[i],ptr,3)==0)
  46.                     break;
  47.             }
  48.             if(i<7)
  49.                 out->tm_wday=i;    /* found day */
  50.             else
  51.             {
  52.                 for(i=0;i<12;i++)
  53.                 {
  54.                     if(strnicmp(month[i],ptr,3)==0)
  55.                         break;
  56.  
  57.                 }
  58.                 if(i<12)
  59.                     out->tm_mon=i;    /* found month */
  60.                 else
  61.                 {
  62.                     if(strnicmp(ptr,"pm",2)==0)
  63.                         out->tm_hour+=12;    /* found PM */
  64.                 }
  65.             }
  66.  
  67.         }
  68.  
  69.         if(isdigit(*ptr))
  70.         {
  71.             if(strchr(ptr,':'))    /* this is an hour */
  72.             {
  73.                 out->tm_hour+=atoi(ptr);
  74.                 ptr=strchr(ptr,':');
  75.                 if(ptr)
  76.                 {
  77.                     ptr++;
  78.                     out->tm_min=atoi(ptr);
  79.                     ptr=strchr(ptr,':');
  80.                     if(ptr)
  81.                     {
  82.                         ptr++;
  83.                         out->tm_sec=atoi(ptr);
  84.                     }
  85.                 }
  86.             }
  87.             else /* not an hour */
  88.             {
  89.                 i=atoi(ptr);
  90.                 if((i<32) && (i>0))    /* day */
  91.                     out->tm_mday=i;
  92.                 else if(i>1969) /* full year */
  93.                     out->tm_year=i-1900;
  94.                 else if((i<100) && (i>69)) /* short year */
  95.                     out->tm_year=i;
  96.                 /*
  97.                      This routine will not work for short years after
  98.                     Jan. 1st 2000, but anyway this program will not be
  99.                     used anymore by this time :-)
  100.                 */
  101.             }
  102.         }
  103.     } while((ptr=strtok(NULL,", "))!=NULL);
  104.  
  105.     if((out->tm_year==0) || (out->tm_mon==0) || (out->tm_mday==0))
  106.     { /* invalid date use current */
  107.         time(&tt);
  108.         *out=*gmtime(&tt);
  109.     }
  110.  
  111.     if(mktime(out)==(time_t)-1) /* fill empty fields */
  112.     { /* bad date ? */
  113.         time(&tt);
  114.         *out=*gmtime(&tt);
  115.     }
  116. }
  117.  
  118. /*
  119.  *    Get the internet address and the user name from a From: field
  120.  */
  121.  
  122. void norm_rfc(char *in, char *outaddr, char *outname)
  123. {
  124.     char *ptr;
  125.  
  126.     if((ptr=strchr(in,'('))!=NULL)
  127.     {
  128.         *ptr='\0';
  129.         ptr++;
  130.         strcpy(outaddr,in);
  131.         strcpy(outname,ptr);
  132.         ptr=strchr(outname,')');
  133.         if(ptr)
  134.             *ptr='\0';
  135.     }
  136.     else if((ptr=strchr(in,'<'))!=NULL)
  137.     {
  138.         *ptr='\0';
  139.         ptr++;
  140.         strcpy(outname,in);
  141.         strcpy(outaddr,ptr);
  142.         ptr=strchr(outaddr,'>');
  143.         if(ptr)
  144.             *ptr='\0';
  145.     }
  146.     else
  147.     {
  148.         strcpy(outaddr,in);
  149.         strcpy(outname,"");
  150.     }
  151.     killendspace(outaddr);
  152.     killendspace(outname);
  153. }
  154.  
  155. /*
  156.  *    Removes spaces at the end of a string
  157.  */
  158.  
  159. void killendspace(char *s)
  160. {
  161.     int end=strlen(s);
  162.  
  163.     while(end>0)
  164.     {
  165.         end--;
  166.         if(s[end]!=' ')
  167.             break;
  168.         s[end]=0;
  169.     }
  170. }
  171.  
  172. /*
  173.  * Convert a fidonet address string ("1:1/1") to ints
  174.  */
  175.  
  176. int fido2ints(char *in, int *zone, int *net, int *node, int *point)
  177. {
  178.     char *ptr;
  179.  
  180.     *zone=0;
  181.     *node=0;
  182.     *net=0;
  183.     *point=0;
  184.  
  185.     ptr=in;
  186.  
  187.     /* zone */
  188.     if(!isdigit(*ptr))
  189.         return FAIL;
  190.     *zone=atoi(ptr);
  191.  
  192.     /* net */
  193.     ptr=strchr(ptr,':');
  194.     if(!ptr)
  195.         return FAIL;
  196.     if(!isdigit(*++ptr))
  197.         return FAIL;
  198.     *net=atoi(ptr);
  199.  
  200.     /* node */
  201.     ptr=strchr(ptr,'/');
  202.     if(!ptr)
  203.         return FAIL;
  204.     if(!isdigit(*++ptr))
  205.         return FAIL;
  206.     *node=atoi(ptr);
  207.  
  208.     /* point */
  209.     *point=0;
  210.     ptr=strchr(ptr,'.');
  211.     if(ptr)
  212.     {
  213.         if(isdigit(*++ptr))
  214.             *point=atoi(ptr);
  215.     }
  216.     if(*zone==0 || *net==0)
  217.         return FAIL;
  218.  
  219.     return SUCCESS;
  220. }
  221.  
  222. /*
  223.  *     Convert a fidonet address to rfc
  224.  *
  225.  *    outaddr: joe.user@<uuname>.fidonet.org || joe.user@[px].fx.nx.zx.fidonet.org
  226.  *    outsite: fx.nx.zx.fido
  227.  *    outname: joe.user
  228.  *
  229.  *    return fail if node doesn't exist
  230.  */
  231.  
  232. int fido2rfc(BFIDOUSER *fido, char *outaddr, char *outsite, char *outname)
  233.  
  234. {
  235.     int i,j;
  236.  
  237.     /* convert name */
  238.     strcpy(outname,fido->name);
  239.  
  240.     if(strchr(outname,' '))
  241.     { /* at least one space, if no space messages comes probably from
  242.            another (technology) gateway, then mail bijectiveness is likely
  243.            to be lost so maker user "unknown" */
  244.         i=0;
  245.         j=0;
  246.         while(outname[i])
  247.         {
  248. /*
  249.             outname[i]&=0x7F;
  250. */    
  251.             if(outname[i]==' ')
  252.                 outname[i]='.';
  253.             else if(outname[i]=='.')
  254.                 outname[i]='_';
  255.             i++;
  256.         }
  257.     }
  258.     else
  259.         strcpy(outname,"unknown");
  260.  
  261.  
  262.     if ((fido->zone == cf->o_zone) &&
  263.         (fido->net  == cf->o_net)  &&
  264.         (fido->node == cf->o_node)    && 
  265.         (cf->registered==TRUE))
  266.     {
  267.             strcpy(outsite,cf->uuname);
  268.     }
  269.     else
  270.     {
  271.         if (fido->point != 0)
  272.             sprintf (outsite, "p%d.f%d.n%d.z%d", fido->point,fido->node, fido->net, fido->zone);
  273.         else
  274.             sprintf (outsite, "f%d.n%d.z%d", fido->node, fido->net, fido->zone);
  275.     }
  276.  
  277.     sprintf(outaddr,"%s@%s.%s",outname, outsite, finddomain(fido->zone, fido->net, fido->node));
  278.     strcat(outsite,".fido");
  279.  
  280.     return SUCCESS;
  281. }
  282.  
  283. /*
  284.  *        Convert a RFC to fidonet address
  285.  */
  286.  
  287. int rfc2fido(BFIDOUSER *fido, char *netaddr)
  288. {
  289.     int i;
  290.     char rfcaddr[BLFSTR], temp[BLFSTR];
  291.  
  292.     if(strlen(netaddr)>BLFSTR)
  293.         return FAIL;
  294.  
  295. #ifdef DEBUG
  296. printf("rfc2fido: IN: %s\n",netaddr);
  297. #endif
  298.  
  299.     /* is ! & @ mixed ? */
  300.     if((strscan('!',netaddr)>=0) && (strscan('@',netaddr)>=0))
  301.     { /* assumes someroad!<fido-aka>!user@something
  302.             to someroad!<fido-aka>!user */
  303.         netaddr[strscan('@',netaddr)]='\0';
  304.     }
  305.  
  306.     /* something!somehost!<fido-aka>!user to <fido-aka>!user */
  307.     i=-1;
  308.     do
  309.     {
  310.         if(strscan('!',netaddr+i+1)>=0) /* is there another '!' */
  311.             strcpy(rfcaddr,netaddr+i+1);
  312.     }
  313.     while( (i=strscan('!',netaddr+i+1))>=0 );
  314.  
  315.     /* user@<fido-aka> to <fido-aka>!user */
  316.     i=strscan('@',netaddr);
  317.     if(i>0)
  318.     {
  319.         netaddr[i]='\0';
  320.         strcpy(rfcaddr,netaddr+i+1);
  321.         strcat(rfcaddr,"!");
  322.         strcat(rfcaddr,netaddr);
  323.     }
  324.  
  325.     /* local */
  326.     if(strscan('!',netaddr)<0)
  327.         strcpy(rfcaddr,netaddr);
  328.  
  329.     if(rfcaddr[0]=='\0')
  330.     {
  331.         logline("!Invalid address %s",fido->name);
  332.         return FAIL;
  333.     }
  334.  
  335.     /* rfcaddr == [pxx].fxx.nxx.zxx.<something>ourdomain!Amelie_Cecile.Vloupf */
  336.     strlwr (rfcaddr);
  337.  
  338.     i = strscan ('!', rfcaddr);
  339.     strcpy (fido->name, rfcaddr+i+1);
  340.  
  341.     if (i > 0)
  342.     {
  343.         rfcaddr[i]='\0';
  344.  
  345.         if (rfcaddr[0] == 'p')
  346.         {
  347.             if(sscanf (rfcaddr, "p%d.%s", &fido->point, temp)==2)
  348.                 strcpy (rfcaddr, temp);
  349.             else
  350.                 fido->point=0;
  351.         }
  352.         else
  353.             fido->point = 0;
  354.  
  355.         if (token(cf->uuname, rfcaddr))
  356.         {
  357.             /* allows uuname.ourdomain, uuname.fido, uuname */
  358.             fido->node = cf->o_node;
  359.             fido->net = cf->o_net;
  360.             fido->zone = cf->o_zone;
  361.         }
  362.         else
  363.         {
  364.             if(sscanf (rfcaddr, "f%d.n%d.z%d.%s", &fido->node, &fido->net, &fido->zone, temp)!=4)
  365.             {
  366.                 logline("-Invalid address %s",rfcaddr);
  367.                 return FAIL;
  368.             }
  369.  
  370. #ifdef STRICTDOMAINCHECK
  371.             if(strcmp(temp,"fidonet.org") && strcmp(temp,"fido"))
  372.             {
  373. #ifndef ALTERDOM
  374.                 logline("?Invalid domain %s in %s",temp,rfcaddr);
  375.                 return FAIL;
  376. #endif
  377.             }
  378. #endif
  379.         }
  380.     }
  381.     else /* assumes local */
  382.     {
  383.         fido->point = 0;
  384.         fido->node = cf->o_node;
  385.         fido->net = cf->o_net;
  386.         fido->zone = cf->o_zone;
  387.     }
  388.  
  389.     /* convert amelie-cecile{.|_}vloupf to Amelie.Cecile Vloupf */
  390.     if (stricmp(fido->name, "postmaster")==0)
  391.         strcpy (fido->name, "Sysop");
  392.     else
  393.     {
  394.         fido->name[0] = (char) toupper(fido->name[0]);
  395.         
  396.         for(i=0;i<((int)strlen(fido->name));i++)
  397.         {
  398.             switch(fido->name[i])
  399.             {
  400.                 case '.':
  401.                 case '_':
  402.                 fido->name[i]=' ';
  403.                 break;
  404.                 case '-':
  405.                 fido->name[i]='.';
  406.                 break;
  407.             }
  408.             
  409.             /* capitalize first letter of names */
  410.            if(isalpha(fido->name[i+1]) && (fido->name[i]==' ' || fido->name[i]=='.'))
  411.                 fido->name[i+1]=(char) toupper(fido->name[i+1]);
  412.             
  413.        }
  414.     }
  415.  
  416. #ifdef DEBUG
  417. printf("rfc2fido: OUT: %s @ %d:%d/%d.%d\n",
  418.         fido->name,fido->zone,fido->net,fido->node,fido->point);
  419. #endif
  420.     return SUCCESS;
  421. }
  422.  
  423. /*
  424.  *    Bounce net file
  425.  *
  426.  *    type:    BOUNCE or WARNING
  427.  * reason:    text describing reason (may be NULL)
  428.  *    to:        RFC address of original author
  429.  *    origmsgid, origmsgto: info about original msg
  430.  */
  431.  
  432. int bounce_net(int type, char *reason, char *to, char *origmsgid,
  433.                 char *origmsgto)
  434. {
  435.     FILE *msg;
  436.     char rreason[BLFSTR];
  437.     char rto[BLFSTR];
  438.     char rid[BLFSTR];
  439.     char date[BLFSTR];
  440.  
  441.     time_t now;
  442.  
  443.     if(origmsgid)
  444.         strcpy(rid,origmsgid);
  445.     else
  446.         strcpy(rid,"Unknown");
  447.  
  448.     if(origmsgto)
  449.         strcpy(rto,origmsgto);
  450.     else
  451.         strcpy(rto,"Unknown");
  452.  
  453.     if(reason)
  454.         strcpy(rreason,reason);
  455.     else
  456.         strcpy(rreason,"Unknown reason.");
  457.  
  458.     /* open output file */
  459.     msg = create_rfcfile(cf->outrfc,"rfc");
  460.     if(!msg)
  461.     {
  462.         logline("*Error while trying to bounce msg to %s",to);
  463.         return FAIL;
  464.     }
  465.  
  466.     /* ! timezone must be set correctly by libs */
  467.     time(&now);
  468.     strftime(date,BLFSTR,"%a, %d %b %y %H:%M:%S %Z",localtime(&now));
  469.  
  470. #ifdef BATCHSMTP
  471.     /* BATCH SMTP Header */
  472.     fprintf(msg,"HELO suntopo.matups.fr\n"); /* fixme: get from config */
  473.     fprintf(msg,"MAIL FROM:<>\n"); /* bounce file, empty from */
  474.     fprintf(msg,"RCPT TO:<%s>\n",to);
  475.     fprintf(msg,"DATA\n");
  476. #endif
  477.     fprintf (msg, "From: postmaster@%s.%s (System Administrator)\n", cf->uuname, finddomain(cf->o_zone,cf->o_net,cf->o_node));
  478.  
  479.     fprintf (msg, "Message-ID: <bounce_%ld@%s.%s>\n",
  480.                     (long) time(NULL), cf->uuname, finddomain(cf->o_zone,cf->o_net,cf->o_node));
  481.  
  482.     fprintf (msg, "To: %s\n", to);
  483.     fprintf (msg, "Date: %s\n", date);
  484.     if(type==BOUNCE)
  485.         fprintf (msg, "Subject: Message bounced.\n");
  486.     else
  487.         fprintf (msg, "Subject: Mailer warning.\n");
  488.  
  489.     fprintf (msg, "Organization: Fido/Usenet Gateway\n");
  490.     fputc ('\n', msg);
  491.  
  492.     /* msg itself */
  493.     if(type==BOUNCE)
  494.     {
  495.         fprintf(msg,"   %s.%s was unable to process the message you sent to:\n\n     %s\n\n",
  496.              cf->uuname,finddomain(cf->o_zone,cf->o_net,cf->o_node),rto);
  497.          fprintf(msg, "   for the following reason: %s\n\n",rreason);
  498.     }
  499.     else
  500.     {
  501.         fprintf(msg,"   You sent a message to %s through %s.%s,\n",
  502.             rto,cf->uuname,finddomain(cf->o_zone,cf->o_net,cf->o_node));
  503.         fprintf(msg,"   your mail may not arrive for the following reason:\n"
  504.                 "   %s\n",rreason);
  505.     }
  506.  
  507.     fprintf(msg, "   Original message Id: %s\n\n\n",rid);
  508.     fprintf(msg, "   If you have any question, contact postmaster@%s.%s\n\n\n\n",
  509.                 cf->uuname,finddomain(cf->o_zone,cf->o_net,cf->o_node));
  510.     fprintf(msg,"   (this message was automatically generated by\n%s %s)\n\n",ProgName,Version);
  511.     /* signature */
  512.     fprintf (msg, "\n---\n      postmaster@%s.%s\n", cf->uuname, finddomain(cf->o_zone,cf->o_net,cf->o_node));
  513.  
  514. #ifdef BATCHSMTP
  515.     fprintf(msg,".\nQUIT\n");
  516. #endif
  517.  
  518.     logline("*Message from %s to %s bounced",to,rto);
  519.     logline("*Reason: %s",rreason);
  520.     fclose(msg);
  521.  
  522.     return SUCCESS;
  523. }
  524.  
  525. /*
  526.  *    Bounce to fido
  527.  */
  528.  
  529. void bounce_fido(int type, char *reason, BFIDOUSER *bb, char *origmsgto)
  530. {
  531.     FILE *pkt;
  532.     char rto[BLFSTR];
  533.     char rreason[BLFSTR];
  534.     BFIDOUSER from;
  535.  
  536.     init_user(from,"Uucp Gateway",cf->o_zone,cf->o_net,cf->o_node,cf->o_point);
  537.     
  538.     if(!origmsgto)
  539.         strcpy(rto,"unknown");
  540.     else
  541.         strcpy(rto,origmsgto);
  542.  
  543.     if(!reason)
  544.         strcpy(rreason,"unknown reason");
  545.     else
  546.         strcpy(rreason,reason);
  547.  
  548.     pkt=openpacket();
  549.     if(pkt)
  550.     {
  551.         if(type==BOUNCE)
  552.         {
  553.             openpktmessage(pkt,NULL,&from,bb,"Message bounced",0,NULL);
  554.             fprintf(pkt,"\r\rThe message you sent to %s\rwas bounced at %d:%d/%d.%d ",
  555.                     rto,cf->o_zone,cf->o_net,cf->o_node,cf->o_point);
  556.             fprintf(pkt,"for the following reason:\r%s\r\r",rreason);
  557.         }
  558.         else
  559.         {
  560.             openpktmessage(pkt,NULL,&from,bb,"Warning from uucp mailer",0,NULL);
  561.             fprintf(pkt,"\r\rWhile processing the message you sent to %s\r",rto);
  562.             fprintf(pkt,"the uucp mailer at %d:%d/%d.%d issued the following warning:\r%s\r\r",
  563.                     cf->o_zone,cf->o_net,cf->o_node,cf->o_point,rreason);
  564.         }
  565.  
  566.         if(cf->magic[0])
  567.         {
  568.             fprintf(pkt,"For more information on the UUCP Gateway you can request\r"
  569.                         "the magic file %s at node %d:%d/%d\r\r",cf->magic,
  570.                         cf->o_zone, cf->o_net, cf->o_node);
  571.         }
  572.  
  573.         fprintf(pkt,"=== %s v%s\r",ProgName,Version);
  574.         closepktmessage(pkt);
  575.         closepacket(pkt);
  576.     }
  577.     logline("*Message from %s (%d:%d/%d.%d) to %s %s.",bb->name,bb->zone,
  578.                 bb->net,bb->node,bb->point,rto, type==BOUNCE ? "Bounced":"-> Warning");
  579.     logline("*Reason: %s",rreason);
  580. }
  581.  
  582. /* end of address.c */
  583.